#include "../userprog/syscall.h"

/*/======== Function that returns the index of the biggest row ========*/
int getBiggestRow()
{
	int r;
	int biggestRow = 0;
	int biggestRowSize;
	int freeSeats;
	int SCREENING_ROOM_ROWS;
	biggestRowSize = getNumFreeSeats(0);
	SCREENING_ROOM_ROWS = CreateMV(1, "SCREENING_ROOM_ROWS", 19);
	for(r = 1; r < GetMV(SCREENING_ROOM_ROWS,0); r++)
	{
		freeSeats = getNumFreeSeats(r);
		
		if(freeSeats > biggestRowSize)
		{
			biggestRow = r;
			biggestRowSize = getNumFreeSeats(r);
		}
	}
	
	return biggestRow;
}

/*/======== Function that returns the number of free seats in a screening room row ========*/
int getNumFreeSeats(int row)
{
	int SCREENING_ROOM_COLS;
	int SCREENING_ROOM_ROWS;
	int screeningRoomSeat;
	int freeSeats = 0;
	int col;
	SCREENING_ROOM_ROWS = CreateMV(1,"SCREENING_ROOM_ROWS",19);
	SCREENING_ROOM_COLS = CreateMV(1, "SCREENING_ROOM_COLS", 19);
	screeningRoomSeat = CreateMV(GetMV(SCREENING_ROOM_ROWS,0),"screeningRoomSeat",17);
	for(col = 0; col < GetMV(SCREENING_ROOM_COLS,0); col++)
	{
		if(GetMV(GetMV(screeningRoomSeat, row), col) < 0)
		{
			freeSeats++;
		}
	}
	return freeSeats;
}

/*/======== Function that returns the index of the smallest row that fits a specified number of people ========*/
int getSmallestRowThatFits(int numPeopleToSeat)
{
	int r;
	int q;
	int rowThatFitsExists = 0;
	int smallestRowThatFits = -1;
	int SCREENING_ROOM_ROWS = CreateMV(1, "SCREENING_ROOM_ROWS", 19);
	for(r = 0; r < GetMV(SCREENING_ROOM_ROWS,0); r++)
	{
		if(getNumFreeSeats(r) >= numPeopleToSeat)
		{
			smallestRowThatFits = r;
			rowThatFitsExists = 1;
			break;
		}
	}
	
	if(smallestRowThatFits == -1)
	{
		return -1;
	}
	else
	{
		int smallestRowThatFitsSize = getNumFreeSeats(smallestRowThatFits);
		for(q = 0; q < GetMV(SCREENING_ROOM_ROWS,0); q++)
		{
			int numFreeSeats = getNumFreeSeats(q);
			if(numFreeSeats >= numPeopleToSeat && numFreeSeats < smallestRowThatFitsSize)
			{
				smallestRowThatFits = q;
				smallestRowThatFitsSize = getNumFreeSeats(q);
			}
		}
		
		return smallestRowThatFits;
	}
}






/*/======== Customer Function ========*/
void main()
{
	int myIndex;
	int customerIndex;
	int needSeats;
	int smallestRowThatFits;
	int biggestRow;
	int biggestRowSize;
	int fillCol;
	int leavingSeatIndex;
	
	int myGroupSize;
	
	int myTicketClerk;
	int myConcessionClerk;
	int myTicketTaker;
	
	int shortestTCLineLength;
	int shortestCCLineLength;
	int shortestTTLineLength;
	
	int numPopcornToOrder;
	int numSodaToOrder;
	
	int proceedToScreeningRoom;
	
	int myLobby;
	
	int bathroomWanted;
	int roll1;
	
	/*Counters*/
	int i1;
	int i2;
	int i3;
	int i4;
	int i5;
	int i6;
	int i7;
	int i8;
	int i9;
	
	
	int c1;
	int r1;


/*Shared Data*/
int numCustomersInTheaterLock;
int numCustomersInTheater;
int numGroupsInTheaterLock;
int numGroupsInTheater;
int customerInitLock;
int customerStartLock;
int customerInitCondition;
int customerStartCondition;
int tcInteractionLock;
int tcInteractionCondition;
int ccInteractionLock;
int ccInteractionCondition;
int ttInteractionLock;
int ttInteractionCondition;
int NUM_TICKET_CLERKS;
int NUM_CUSTOMERS;
int CUSTOMER_INIT_MODE;
int CONSTANT_NUMBER_OF_CUSTOMERS;
int MAX_GROUP_SIZE;
int PRINT_DEBUG_MESSAGES;
int PRINT_OUTPUT_MESSAGES;
int PRINT_TEST_CASE_MESSAGES;
int latestIndex;
int overrideExitLock;
int overrideExitCondition;
int tcLineManager;
int ccLineManager;
int ttLineManager;
int tcState;
int ccState;
int ttState;
int tcLineLength;
int ccLineLength;
int ttLineLength;
int tcLineCondition;
int ccLineCondition;
int ttLineCondition;
int CLERK_AVAILABLE;
int CLERK_BUSY;
int CLERK_ON_BREAK;
int TICKET_PRICE;
int POPCORN_PRICE;
int SODA_PRICE;
int numTicketsDesired;
int numPopcornDesired;
int numSodaDesired;
int NUM_CONCESSION_CLERKS;
int CUSTOMER_WANT_POPCORN_PROBABILITY;
int CUSTOMER_WANT_SODA_PROBABILITY;
int CUSTOMER_WANT_BATHROOM_PROBABILITY;
int NUM_TICKET_TAKERS;
int ticketTakerFull;
int ttForcedToStop;
int ttLobbyLock;
int ttLobbyCondition;
int numTicketsGiven;
int ticketTakerSaidToProceed;
int screeningRoomLock;
int movieInProgressLock;
int movieInProgressCondition;

int SCREENING_ROOM_ROWS;
int SCREENING_ROOM_COLS;
int screeningRoomSeat;/*//array of screening room row MV pointers AKA all the seats
//int screeningRoomRow;//array of seat booleans (columns within one row), AKA a row (this variable is not used by the customer directly)
//to access a specific seat [row][column] you'd have to do
//GetMV(GetMV(screeningRoomSeat, row), column)
//instead of screeningRoomSeat[row][col]
//to set a seat:
//SetMV(GetMV(screeningRoomseat, row), column, VALUE)
//I think.....
//2D arrays shared via monitor variables are a bitch, wtf...*/

/*Acquire Shared Data*/
NUM_TICKET_CLERKS = CreateMV(1,"NUM_TICKET_CLERKS", 17);
NUM_CONCESSION_CLERKS = CreateMV(1,"NUM_CONCESSION_CLERKS", 21);
NUM_TICKET_TAKERS = CreateMV(1, "NUM_TICKET_TAKERS", 17);
SCREENING_ROOM_COLS = CreateMV(1, "SCREENING_ROOM_COLS", 19);
SCREENING_ROOM_ROWS = CreateMV(1, "SCREENING_ROOM_ROWS", 19);

numCustomersInTheaterLock = CreateLock("numCustomersInTheaterLock", 25);
numCustomersInTheater = CreateMV(1, "numCustomersInTheater", 21);
numGroupsInTheaterLock = CreateLock("numGroupsInTheaterLock", 22);
numGroupsInTheater = CreateMV(1,"numGroupsInTheater", 18);
customerInitLock = CreateLock("customerInitLock", 16);
customerStartLock = CreateLock("customerStartLock", 17);
customerInitCondition = CreateCondition("customerInitCondition", 21);
customerStartCondition = CreateCondition("customerStartCondition", 22);
tcInteractionLock = CreateMV(GetMV(NUM_TICKET_CLERKS,0), "tcInteractionLock", 17);
tcInteractionCondition = CreateMV(GetMV(NUM_TICKET_CLERKS,0), "tcInteractionCondition", 22);
ccInteractionLock = CreateMV(GetMV(NUM_CONCESSION_CLERKS,0), "ccInteractionLock", 17);
ccInteractionCondition = CreateMV(GetMV(NUM_CONCESSION_CLERKS,0), "ccInteractionCondition", 22);
ttInteractionLock = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ttInteractionLock", 17);
ttInteractionCondition = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ttInteractionCondition", 22);

NUM_CUSTOMERS = CreateMV(1,"NUM_CUSTOMERS", 13);
CUSTOMER_INIT_MODE = CreateMV(1,"CUSTOMER_INIT_MODE", 18);
CONSTANT_NUMBER_OF_CUSTOMERS = CreateMV(1,"CONSTANT_NUMBER_OF_CUSTOMERS", 28);
MAX_GROUP_SIZE = CreateMV(1,"MAX_GROUP_SIZE",14);
PRINT_DEBUG_MESSAGES = CreateMV(1, "PRINT_DEBUG_MESSAGES", 20);
PRINT_OUTPUT_MESSAGES = CreateMV(1, "PRINT_OUTPUT_MESSAGES", 21);
PRINT_TEST_CASE_MESSAGES = CreateMV(1, "PRINT_TEST_CASE_MESSAGES", 24);
latestIndex = CreateMV(1,"latestIndex", 11);
overrideExitLock = CreateLock("overrideExitLock", 16);
overrideExitCondition = CreateCondition("overrideExitCondition", 21);
tcLineManager = CreateLock("tcLineManager", 13);
ccLineManager = CreateLock("ccLineManager", 13);
ttLineManager = CreateLock("ttLineManager", 13);
tcState = CreateMV(GetMV(NUM_TICKET_CLERKS,0),"tcState", 7 );
ccState = CreateMV(GetMV(NUM_CONCESSION_CLERKS,0),"ccState", 7);
ttState = CreateMV(GetMV(NUM_TICKET_TAKERS,0),"ttState", 7);
tcLineLength = CreateMV(GetMV(NUM_TICKET_CLERKS,0), "tcLineLength", 12);
ccLineLength = CreateMV(GetMV(NUM_CONCESSION_CLERKS,0), "ccLineLength", 12);
ttLineLength = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ttLineLength", 12);
tcLineCondition = CreateMV(GetMV(NUM_TICKET_CLERKS, 0), "tcLineCondition", 15);
ccLineCondition = CreateMV(GetMV(NUM_CONCESSION_CLERKS, 0), "ccLineCondition", 15);
ttLineCondition = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ttLineCondition", 15);
CLERK_AVAILABLE = CreateMV(1,"CLERK_AVAILABLE", 15);
CLERK_BUSY = CreateMV(1, "CLERK_BUSY", 10);
CLERK_ON_BREAK = CreateMV(1, "CLERK_ON_BREAK", 14);
TICKET_PRICE = CreateMV(1, "TICKET_PRICE", 12);
POPCORN_PRICE = CreateMV(1, "POPCORN_PRICE", 13);
SODA_PRICE = CreateMV(1, "SODA_PRICE", 10);
numTicketsDesired = CreateMV(GetMV(NUM_TICKET_CLERKS,0), "numTicketsDesired", 17);
numPopcornDesired = CreateMV(GetMV(NUM_CONCESSION_CLERKS,0), "numPopcornDesired", 17);
numSodaDesired = CreateMV(GetMV(NUM_CONCESSION_CLERKS,0), "numSodaDesired", 14);

CUSTOMER_WANT_POPCORN_PROBABILITY = CreateMV(1, "CUSTOMER_WANT_POPCORN_PROBABILITY", 32);
CUSTOMER_WANT_SODA_PROBABILITY = CreateMV(1, "CUSTOMER_WANT_SODA_PROBABILITY", 30);
CUSTOMER_WANT_BATHROOM_PROBABILITY = CreateMV(1, "CUSTOMER_WANT_BATHROOM_PROBABILITY", 34);

ticketTakerFull = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ticketTakerFull", 15);
ttForcedToStop = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ttForcedToStop", 14);
ttLobbyLock = CreateMV(GetMV(NUM_TICKET_TAKERS,0) + 1, "ttLobbyLock", 11);
ttLobbyCondition = CreateMV(GetMV(NUM_TICKET_TAKERS, 0) + 1, "ttLobbyCondition", 16);
numTicketsGiven = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "numTicketsGiven", 15);
ticketTakerSaidToProceed = CreateMV(GetMV(NUM_TICKET_TAKERS,0), "ticketTakerSaidToProceed", 24);

screeningRoomSeat = CreateMV(GetMV(SCREENING_ROOM_ROWS,0), "screeningRoomSeat", 17);
screeningRoomLock = CreateLock("screeningRoomLock", 17);
movieInProgressLock = CreateLock("movieInProgressLock", 19);
movieInProgressCondition = CreateCondition("movieInProgressCondition", 24);
/**/	
	
	myIndex = GetMV(latestIndex,0);
	
	/*/Create a random sized group of followers*/
	myGroupSize = RandInt() % GetMV(MAX_GROUP_SIZE,0) + 1;
	
	/*/Synchronization so number of customers in theater is maintained*/
	AcquireLock(numCustomersInTheaterLock);
	SetMV(numCustomersInTheater, 0, (GetMV(numCustomersInTheater, 0) + myGroupSize));
	while(GetMV(numCustomersInTheater, 0) > GetMV(NUM_CUSTOMERS, 0) && GetMV(CUSTOMER_INIT_MODE, 0) == GetMV(CONSTANT_NUMBER_OF_CUSTOMERS, 0))
	{
		myGroupSize--;
		SetMV(numCustomersInTheater, 0, GetMV(numCustomersInTheater,0) - 1);
	}
	ReleaseLock(numCustomersInTheaterLock);
	AcquireLock(numGroupsInTheaterLock);
	SetMV(numGroupsInTheater, 0, GetMV(numGroupsInTheater, 0) + 1);
	ReleaseLock(numGroupsInTheaterLock);
	
	/*/Only one customer can be initialized at a time*/
	AcquireLock(customerInitLock);
	AcquireLock(customerStartLock);
	/*
	int myTicketClerk;
	int myConcessionClerk;
	int myTicketTaker;
	*/
	SignalCondition(customerInitCondition, customerInitLock);
	ReleaseLock(customerInitLock);
	WaitCondition(customerStartCondition, customerStartLock);
	
	ReleaseLock(customerStartLock);
	
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: entered the theater with group size of %d\n", 56, 2, myIndex*100 + myGroupSize);
	for(i1 = 0; i1 < myGroupSize; i1++)
	{
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in Group %d has entered the movie theater.\n", 56, 2, i1*100 + myIndex);
		Yield();
	}
	
	/*/================ Go To Ticket Clerk ================*/
	
	/*/special case for testing*/
	if(GetMV(NUM_TICKET_CLERKS, 0) == 0)
	{
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: ERROR: No TicketClerks in theater!\n", 49, 1, myIndex);
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d: No ConcessionClerks found, leaving theater...\n", 57, 1, myIndex);
		
		AcquireLock(numCustomersInTheaterLock);
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numCustomersInTheater\n", 49, 1, myIndex);
		SetMV(numCustomersInTheater, 0, GetMV(numCustomersInTheater, 0) - myGroupSize);
		ReleaseLock(numCustomersInTheaterLock);
		
		AcquireLock(numGroupsInTheaterLock);
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numGroupsInTheater\n", 46, 1, myIndex);
		SetMV(numGroupsInTheater, 0, GetMV(numGroupsInTheater, 0) - 1);
		ReleaseLock(numGroupsInTheaterLock);
		
		AcquireLock(overrideExitLock);
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: leaving theater...\n", 33, 1, myIndex);
		WaitCondition(overrideExitCondition, overrideExitLock);
	}
	
	do
	{
		/*/Begin search for ticket clerks*/
		myTicketClerk = -1;
		
		/*/Lock down all lines from other customers/clerks for search*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: acquiring Lock for TicketClerk search\n", 52, 1, myIndex);
		AcquireLock(tcLineManager);

		/*/See if any TicketClerk line is empty*/
		for(i2 = 0;i2 < GetMV(NUM_TICKET_CLERKS,0);i2++)
		{
			if(GetMV(tcState,i2)== GetMV(CLERK_AVAILABLE,0))
			{
				if(PRINT_TEST_CASE_MESSAGES)
					FPrint("TicketClerk %d has no line\n",28, 1, i2);
				/*/Join an empty line*/
				myTicketClerk = i2;
				SetMV(tcState,myTicketClerk,GetMV(CLERK_BUSY,0));
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: found available TicketClerk %d\n", 45, 2, myIndex*100 + myTicketClerk);
				
				break;
			}
			else if(GetMV(tcState,i2) == GetMV(CLERK_ON_BREAK,0))
			{
				if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees TicketClerk %d is on break\n", 42, 2, myIndex*100 + i2);
			}
		}

		/*/If no lines were empty, join shortest line*/
		if(myTicketClerk  == -1){
			shortestTCLineLength = GetMV(tcLineLength,0);
			
			
			for(i3 = 0;i3 < GetMV(NUM_TICKET_CLERKS,0);i3++)
			{
				if(PRINT_TEST_CASE_MESSAGES)
					FPrint("TicketClerk %d's line length is %d\n", 36, 2, i3*100 + GetMV(tcLineLength,i3));
					
				if(GetMV(tcState,i3) == GetMV(CLERK_BUSY,0) && shortestTCLineLength >= GetMV(tcLineLength,i3))
				{
					myTicketClerk = i3;
					shortestTCLineLength = GetMV(tcLineLength,i3);
				}
				else if(GetMV(tcState,i3) == GetMV(CLERK_ON_BREAK,0))
				{
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees TicketClerk %d is on break\n", 42, 2, myIndex*100 + i3);
				}
			}
			
			if(myTicketClerk == -1)
			{
				/*/If all ticket clerks are on break, wait in lobby*/
				ReleaseLock(tcLineManager);
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: ERROR: all TicketClerks on break\n", 47, 1, myIndex);
				if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d: No TicketClerks found, leaving theater...\n", 53, 1, myIndex);
							
				AcquireLock(numCustomersInTheaterLock);
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numCustomersInTheater\n", 49, 1, myIndex);
				SetMV(numCustomersInTheater,0, GetMV(numCustomersInTheater, 0) - myGroupSize);
				ReleaseLock(numCustomersInTheaterLock);
				
				AcquireLock(numGroupsInTheaterLock);
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numGroupsInTheater\n", 46, 1, myIndex);
				SetMV(numGroupsInTheater, 0, GetMV(numGroupsInTheater, 0) - 1);
				ReleaseLock(numGroupsInTheaterLock);
				
				AcquireLock(overrideExitLock);
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: leaving theater...\n", 33, 1, myIndex);
				WaitCondition(overrideExitCondition, overrideExitLock);
			}
			else
			{
				/*/Get in that line*/
				SetMV(tcLineLength, myTicketClerk, GetMV(tcLineLength,myTicketClerk) + 1);
				
				/*/Wait to be signalled for ticket order*/
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: getting in line for TicketClerk %d\n", 49, 2, myIndex*100 + myTicketClerk);
				WaitCondition(GetMV(tcLineCondition,myTicketClerk), tcLineManager);
			}
		}
	}
	while(myTicketClerk < 0 || GetMV(tcState,myTicketClerk) == GetMV(CLERK_ON_BREAK,0));
	
	/*/Release and allow other customers to search lines*/
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: releasing Lock for TicketClerk search\n", 52, 1, myIndex);
	ReleaseLock(tcLineManager);
		
	/*/After being signalled by TicketClerk to interact, lock down current clerk*/
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: TicketClerk %d is ready for interaction\n", 54, 2, myIndex*100 + myTicketClerk);
	if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is walking up to TicketClerk %d to buy %d tickets.\n", 61, 3, myIndex*10000 + myTicketClerk*100 + myGroupSize);
	AcquireLock(GetMV(tcInteractionLock,myTicketClerk));

	/*/Give ticket order to clerk and signal TicketClerk to wake up*/
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: signalling TicketClerk %d for %d tickets\n", 55, 3,  myIndex*10000 + myTicketClerk*100 + myGroupSize);
	if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d in TicketClerk line %d is paying %d for tickets.\n", 59, 3, myIndex*10000 + myTicketClerk*100 + myGroupSize * GetMV(TICKET_PRICE,0));
	
	SetMV(numTicketsDesired, myTicketClerk, myGroupSize);
	
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: waiting for response\n", 35, 1, myIndex);
	SignalCondition(GetMV(tcInteractionCondition,myTicketClerk), GetMV(tcInteractionLock,myTicketClerk));

	/*/Wait for TicketClerk to give tickets*/
	WaitCondition(GetMV(tcInteractionCondition,myTicketClerk), GetMV(tcInteractionLock,myTicketClerk));
	
	/*/After getting signalled by TicketClerk with completed ticket order*/
	AcquireLock(GetMV(tcInteractionLock,myTicketClerk));
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: received %d tickets from TicketClerk %d\n", 54, 3, myIndex*1000 + (GetMV(numTicketsDesired,myTicketClerk))*100 + myTicketClerk);
	if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is leaving TicketClerk %d\n", 36, 2, myIndex*100 + myTicketClerk);
	SignalCondition(GetMV(tcInteractionCondition,myTicketClerk), GetMV(tcInteractionLock,myTicketClerk));
	ReleaseLock(GetMV(tcInteractionLock,myTicketClerk));
	
	/*/================ Go To Concession Clerk ================*/
	
	/*/special case for testing*/
	if(NUM_CONCESSION_CLERKS == 0)
	{
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: ERROR: No ConcessionClerks in theater!\n", 53, 1, myIndex);
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d: No ConcessionClerks found, leaving theater...\n", 57, 1, myIndex);
		
		AcquireLock(numCustomersInTheaterLock);
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numCustomersInTheater\n", 49, 1, myIndex);
		SetMV(numCustomersInTheater, 0 , GetMV(numCustomersInTheater,0) - myGroupSize);
		ReleaseLock(numCustomersInTheaterLock);
		
		AcquireLock(numGroupsInTheaterLock);
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numGroupsInTheater\n", 46, 1, myIndex);
		SetMV(numGroupsInTheater, 0, GetMV(numGroupsInTheater, 0) - 1);
		ReleaseLock(numGroupsInTheaterLock);
		
		AcquireLock(overrideExitLock);
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: leaving theater...\n", 33, 1, myIndex);
		WaitCondition(overrideExitCondition, overrideExitLock);
	}
	
	/*/Calculate amount of popcorn and soda to order*/
	numPopcornToOrder = 0;
	numSodaToOrder = 0;
	
	for(i4 = 0; i4 < myGroupSize; i4++)
	{
		/*/Randomly select popcorn and soda*/
		int popcornWanted = 0;
		int sodaWanted = 0;
		int roll = RandInt() % 100 + 1;
		
		if(roll <= GetMV(CUSTOMER_WANT_POPCORN_PROBABILITY,0))
		{
			popcornWanted = 1;
			numPopcornToOrder += popcornWanted;
		}
		
		roll = RandInt() % 100 + 1;
		if(roll <= GetMV(CUSTOMER_WANT_SODA_PROBABILITY,0))
		{
			sodaWanted = 1;
			numSodaToOrder += sodaWanted;
		}
		
		Yield();
		
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in group %d wants %d popcorn and %d soda.\n", 55, 4,
			i4*1000000 + myIndex*10000 + popcornWanted*100 + sodaWanted);
	}
	
	/*/If any food is desired, approach ConcessionClerk lines*/
	if(numPopcornToOrder + numSodaToOrder > 0)
	{
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: %d popcorn and %d soda desired\n", 45, 3, myIndex*10000+ numPopcornToOrder*100 + numSodaToOrder);
		
		do
		{
			/*/Begin search for ConcessionClerk*/
			myConcessionClerk = -1;
			
			/*/Lock down all lines from other customers/clerks for search*/
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: acquiring Lock for ConcessionClerk search\n", 56, 1, myIndex);
			AcquireLock(ccLineManager);

			/*/See if any ConcessionClerk line is empty*/
			for(i5 = 0;i5 < GetMV(NUM_CONCESSION_CLERKS,0);i5++)
			{
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: ConcessionClerk %d is in state: %d\n", 49, 3, myIndex*10000 + i5*100 + GetMV(ccState,i5));
				
				if(GetMV(ccState,i5) == GetMV(CLERK_AVAILABLE,0))
				{
					/*/Join an empty line*/
					myConcessionClerk = i5;
					SetMV(ccState,myConcessionClerk, GetMV(CLERK_BUSY,0));
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: found available ConcessionClerk %d\n", 49, 2, myIndex*100 + myConcessionClerk);
					
					break;
				}
				else if(GetMV(tcState,i5) == GetMV(CLERK_ON_BREAK,0))
				{
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees ConcessionClerk %d is on break\n", 46, 2, myIndex*100 + i5);
				}
			}

			/*/If no lines were empty, join shortest line*/
			if(myConcessionClerk  == -1){
				shortestCCLineLength = GetMV(ccLineLength,0);
				
				for(i6 = 0;i6 < GetMV(NUM_CONCESSION_CLERKS,0);i6++)
				{
					if(GetMV(ccState,i6) == GetMV(CLERK_BUSY,0) && shortestCCLineLength >= GetMV(ccLineLength,i6))
					{
						myConcessionClerk = i6;
						shortestCCLineLength = GetMV(ccLineLength,i6);
					}
					else if(GetMV(tcState,i6) == GetMV(CLERK_ON_BREAK,0))
					{
						if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees ConcessionClerk %d is on break\n", 46, 2, myIndex*100 + i6);
					}
				}
				
				if(myConcessionClerk == -1)
				{					
					/*/If all ConcessionClerks are on break, wait in lobby*/
					ReleaseLock(ccLineManager);
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: ERROR: all ConcessionClerks on break!\n", 52, 1, myIndex);
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d: No ConcessionClerks found, leaving theater...\n", 57, 1, myIndex);
					
					AcquireLock(numCustomersInTheaterLock);
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numCustomersInTheater\n", 49, 1, myIndex);
					SetMV(numCustomersInTheater, 0, GetMV(numCustomersInTheater,0) - myGroupSize);
					ReleaseLock(numCustomersInTheaterLock);
					
					AcquireLock(numGroupsInTheaterLock);
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Decrementing numGroupsInTheater\n", 46, 1, myIndex);
					SetMV(numGroupsInTheater, 0, GetMV(numGroupsInTheater,0) - 1);
					ReleaseLock(numGroupsInTheaterLock);
					
					AcquireLock(overrideExitLock);
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: leaving theater...\n", 33, 1, myIndex);
					WaitCondition(overrideExitCondition, overrideExitLock);
				}
				else
				{
					/*/Get in that line*/
					SetMV(ccLineLength, myConcessionClerk, GetMV(ccLineLength,myConcessionClerk) + 1);
					
					/*/Wait to be signalled for food order*/
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: getting in line for ConcessionClerk %d\n", 53, 2, myIndex*100 + myConcessionClerk);
					WaitCondition(GetMV(ccLineCondition,myConcessionClerk), ccLineManager);
				}
			}
		}
		while(myConcessionClerk < 0 || GetMV(ccState,myConcessionClerk) == GetMV(CLERK_ON_BREAK,0));
		
		/*/Release and allow other customers to search lines*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: releasing Lock for ConcessionClerk search\n", 56, 1, myIndex);
		ReleaseLock(ccLineManager);
			
		/*/After being signalled by ConcessionClerk to interact, lock down current clerk*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: ConcessionClerk %d is ready for interaction\n", 58, 2, myIndex*100 + myConcessionClerk);
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is walking up to ConcessionClerk %d to buy %d popcorn and %d soda.\n", 77, 4,
			myIndex*1000000 + myConcessionClerk*10000 + numPopcornToOrder*100 + numSodaToOrder);
		AcquireLock(GetMV(ccInteractionLock,myConcessionClerk));

		/*/Give food order to clerk and signal ConcessionClerk to wake up*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: signalling ConcessionClerk %d for %d popcorn and %d soda\n", 71, 4,
			myIndex*1000000 + myConcessionClerk*10000 + numPopcornToOrder*100 + numSodaToOrder);
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d in ConcessionClerk line %d is paying %d for food.\n", 60, 3,
			myIndex*10000 + myConcessionClerk*100 + numPopcornToOrder * GetMV(POPCORN_PRICE,0) + numSodaToOrder * GetMV(SODA_PRICE,0));
		
		SetMV(numPopcornDesired,myConcessionClerk, numPopcornToOrder);
		SetMV(numSodaDesired,myConcessionClerk, numSodaToOrder);
		
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: waiting for response\n", 35, 1, myIndex);
		SignalCondition(GetMV(ccInteractionCondition,myConcessionClerk), GetMV(ccInteractionLock,myConcessionClerk));

		/*/Wait for ConcessionClerk to give food*/
		WaitCondition(GetMV(ccInteractionCondition,myConcessionClerk), GetMV(ccInteractionLock,myConcessionClerk));
		
		/*/After getting signalled by ConcessionClerk with completed ticket order*/
		AcquireLock(GetMV(ccInteractionLock,myConcessionClerk));
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: received %d popcorn and %d soda from ConcessionClerk %d\n", 70, 4,
			myIndex*1000000 + GetMV(numPopcornDesired,myConcessionClerk)*10000 + GetMV(numSodaDesired,myConcessionClerk)*100 + myConcessionClerk);
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is leaving ConcessionClerk %d\n", 40, 2, myIndex*100 + myConcessionClerk);
		
		SignalCondition(GetMV(ccInteractionCondition,myConcessionClerk), GetMV(ccInteractionLock,myConcessionClerk));
		ReleaseLock(GetMV(ccInteractionLock,myConcessionClerk));
	}
	else
	{
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: no food desired, skipping ConcessionClerks\n", 57, 1, myIndex);
	}
	
	/*/=============== Go To TicketTaker ================*/
	
	/*/Flag controlling whether the TicketTaker has allowed the Customer in*/
	proceedToScreeningRoom = 0;
	
	do
	{
		do
		{
			/*/Begin search for TicketTakers*/
			myTicketTaker = -1;
			
			/*/Lock down all lines from other customers/clerks for search*/
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: acquiring ttLineManager\n", 38, 1, myIndex);
			AcquireLock(ttLineManager);

			/*/See if any TicketTaker line is empty*/
			for(i7 = 0;i7 < GetMV(NUM_TICKET_TAKERS,0);i7++)
			{
				if(GetMV(ttState,i7) == GetMV(CLERK_AVAILABLE,0) && !GetMV(ticketTakerFull,i7) && !GetMV(ttForcedToStop,i7))
				{
					/*/Join an empty line*/
					myTicketTaker = i7;
					SetMV(ttState,myTicketTaker, GetMV(CLERK_BUSY,0));
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: found available TicketTaker %d\n", 45, 2, myIndex*100 + myTicketTaker);
					
					break;
				}
				else if(GetMV(ttState,i7) == GetMV(CLERK_ON_BREAK,0))
				{
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees TicketTaker %d is on break\n", 42, 2, myIndex*100 + i7);
				}
			}

			/*/If no lines were empty, join shortest line*/
			if(myTicketTaker  == -1)
			{
				shortestTTLineLength = GetMV(ttLineLength,0);
				
				for(i8 = 0;i8 < GetMV(NUM_TICKET_TAKERS,0);i8++)
				{
					if(GetMV(ttState,i8) == GetMV(CLERK_BUSY,0) && shortestTTLineLength >= GetMV(ttLineLength,i8) && !GetMV(ticketTakerFull,i8) && !GetMV(ttForcedToStop,i8))
					{
						myTicketTaker = i8;
						shortestTTLineLength = GetMV(ttLineLength,i8);
					}
					else if(GetMV(ttState,i8) == GetMV(CLERK_ON_BREAK,0))
					{
						if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees TicketTaker %d is on break\n", 42, 2, myIndex*100 + i8);
					}
				}
				
				if(myTicketTaker == -1)
				{
					ReleaseLock(ttLineManager);
					
					/*/If all TicketTakers are on break, wait in lobby*/
					myLobby = GetMV(NUM_TICKET_TAKERS,0);					
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: all TicketTakers full or on break, going to lobby %d\n", 67, 2, myIndex*100 + myLobby);
					
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: acquiring ttLobbyLock %d\n", 39, 2, myIndex*100 + myLobby);
					AcquireLock(GetMV(ttLobbyLock,myLobby));
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is in the lobby\n", 26, 1, myIndex);
					WaitCondition(GetMV(ttLobbyCondition,myLobby), GetMV(ttLobbyLock,myLobby));
					
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: signalled out of lobby, releasing ttLobbyLock %d\n", 63, 2, myIndex*100 + myLobby);
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is leaving the the lobby\n", 35, 1, myIndex);
					ReleaseLock(GetMV(ttLobbyLock,myLobby));
				}
				else
				{
					/*/Get in that line*/
					SetMV(ttLineLength,myTicketTaker, GetMV(ttLineLength,myTicketTaker) + 1);
					
					/*/Wait to be signalled for ticket order*/
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: getting in line for TicketTaker %d\n", 49, 2, myIndex*100 + myTicketTaker);
					
					WaitCondition(GetMV(ttLineCondition,myTicketTaker), ttLineManager);
				}
			} 
			/*/Release and allow other customers to search lines*/
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: releasing ttLineManager\n", 38, 1, myIndex);
			ReleaseLock(ttLineManager);
		}
		while(myTicketTaker < 0 || GetMV(ttState,myTicketTaker) == GetMV(CLERK_ON_BREAK,0) || GetMV(ticketTakerFull,myTicketTaker) || GetMV(ttForcedToStop,myTicketTaker));	
		
			
		/*/After being signalled by TicketTaker to interact, lock down current clerk*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: TicketTaker %d is ready for interaction. Acquiring ttInteractionLock[%d]\n", 87, 3, myIndex*10000 + myTicketTaker*100 + myTicketTaker);
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is walking up to TicketTaker %d to give %d tickets.\n", 62, 3, myIndex*10000 + myTicketTaker*100 + myGroupSize);
		AcquireLock(GetMV(ttInteractionLock,myTicketTaker));

		/*/Give ticket order to clerk and signal TicketTaker to wake up*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: signalling TicketTaker %d with %d tickets\n", 56, 3, myIndex*10000 + myTicketTaker*100 + myGroupSize);
		
		SetMV(numTicketsGiven,myTicketTaker,myGroupSize);
		SignalCondition(GetMV(ttInteractionCondition,myTicketTaker), GetMV(ttInteractionLock,myTicketTaker));

		/*/Wait for TicketTaker to accept tickets or send to lobby*/
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: acquiring ttLobbyLock %d\n", 39, 2, myIndex*100 + myTicketTaker);
		AcquireLock(GetMV(ttLobbyLock,myTicketTaker));
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: waiting for response on ttInteractionLock%d\n", 58, 2, myIndex*100 + myTicketTaker);
		WaitCondition(GetMV(ttInteractionCondition,myTicketTaker), GetMV(ttInteractionLock,myTicketTaker));
		
		/*/After getting signalled by TicketTaker to go to the screening room or lobby	*/
		if(GetMV(ticketTakerSaidToProceed,myTicketTaker))
		{
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: gave %d tickets to TicketTaker %d\n", 48, 3, myIndex*10000 + GetMV(numTicketsGiven,myTicketTaker)*100 + myTicketTaker);
			if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d is leaving TicketTaker %d\n", 36, 2, myIndex*100 + myTicketTaker);
			proceedToScreeningRoom = 1;
			ReleaseLock(GetMV(ttLobbyLock,myTicketTaker));
		}
		else
		{
			ReleaseLock(GetMV(ttInteractionLock,myTicketTaker));
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: TicketTaker %d full, waiting on ttLobbyLock %d\n", 61, 3, myIndex*10000 + myTicketTaker*100 + myTicketTaker);
			if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Group %d sees TicketTaker %d is no longer taking tickets.  Going to lobby.\n", 76, 2, myIndex*100 + myTicketTaker);
			WaitCondition(GetMV(ttLobbyCondition,myTicketTaker), GetMV(ttLobbyLock,myTicketTaker));
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Signalled out of lobby, releasing ttLobbyLock %d\n", 63, 2, myIndex*100 + myTicketTaker);
			ReleaseLock(GetMV(ttLobbyLock,myTicketTaker));
		}
	}
	while(!proceedToScreeningRoom);
	
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: proceeding to screening room\n", 43, 1, myIndex);
	SignalCondition(GetMV(ttInteractionCondition,myTicketTaker), GetMV(ttInteractionLock,myTicketTaker));
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Releasing ttInteractionLock[%d]\n", 46, 2, myIndex*100 + myTicketTaker);
	ReleaseLock(GetMV(ttInteractionLock,myTicketTaker));
	
	/*/================ Go To Screening Room ================*/
	
	AcquireLock(screeningRoomLock);
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: figuring out screening room seating\n", 50, 1, myIndex);
	
	/*/Figure out how to seat followers*/
	customerIndex = 0;
	needSeats = myGroupSize;
	
	while(needSeats > 0)
	{
		if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Needs %d more seats\n", 34, 2, myIndex*100 + needSeats);
	
		/*/Try to find the smallest row that fits all group members*/
		smallestRowThatFits = getSmallestRowThatFits(needSeats);
		
		if(smallestRowThatFits >= 0)
		{
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Smallest row that fits: %d with %d free seats\n", 60, 3,
				myIndex*10000 + smallestRowThatFits*100 + getNumFreeSeats(smallestRowThatFits));
		}
		else
		{
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: No rows fit %d people, proceeding to split group\n", 63, 2,
				myIndex*100 + needSeats);
		}
		
		/*/No row that fits all group members found, */
		if(smallestRowThatFits == -1)
		{
			/*/Find biggest row	*/		
			biggestRow = getBiggestRow();
			biggestRowSize = getNumFreeSeats(biggestRow);
			
			fillCol = 0;
			while(fillCol < GetMV(SCREENING_ROOM_COLS,0))
			{
				if(GetMV(GetMV(screeningRoomSeat, biggestRow), fillCol) < 0)
				{				
					/*/Fill the seat*/
					SetMV(GetMV(screeningRoomSeat, biggestRow), fillCol, myIndex);
					
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d in Group %d has found the following seat: row %d and seat %d\n", 74, 4,
						customerIndex*1000000 + myIndex*10000 + biggestRow*100 + fillCol);
					if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in group %d is sitting in a theater room seat.\n", 60, 2,
						customerIndex*100 + myIndex);
					
					/*/Decrement remaining seats, increment current customer*/
					needSeats--;
					customerIndex++;
				}
				
				fillCol++;
			}
			
			/*/Repeat loop with remaining people*/
		}
		else
		{
			/*/Smallest row that fits found, fill row and fill members in*/
			fillCol = 0;
			while(needSeats > 0)
			{	
				if(GetMV(GetMV(screeningRoomSeat, smallestRowThatFits), fillCol) < 0)
				{
					/*/Fill the seat*/
					SetMV(GetMV(screeningRoomSeat, smallestRowThatFits), fillCol, myIndex);
					
					if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Group %d, Customer %d has found the following seat: row %d and seat %d\n", 72, 4,
						myIndex*1000000 + customerIndex*10000 + smallestRowThatFits*100 + fillCol);
					
					/*/Decrement remaining seats, increment current customer*/
					needSeats--;
					customerIndex++;
				}
				
				fillCol++;
			}
		}
	}
	
	/*/Customer group successfully seated*/
	ReleaseLock(screeningRoomLock);
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: whole group successfully seated in theater\n", 57, 1, myIndex);
	
	/*/Wait for movie to start*/
	AcquireLock(movieInProgressLock);
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: waiting for movie to start...\n", 44, 1, myIndex);
	WaitCondition(movieInProgressCondition, movieInProgressLock);
	
	/*/Signalled by MovieTechnician that movie is over	*/
	ReleaseLock(movieInProgressLock);
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: Signalled by MovieTechnician that movie is over\n", 62, 1, myIndex);
	
	/*/Now that movie is over, wait for group to get out of their seats*/
	AcquireLock(screeningRoomLock);
	leavingSeatIndex = 0;
	for(c1 = 0; c1 < GetMV(SCREENING_ROOM_COLS,0); c1++)
	{
		for(r1 = 0; r1 < GetMV(SCREENING_ROOM_ROWS,0); r1++)
		{
			if(GetMV(GetMV(screeningRoomSeat, r1), c1) == myIndex)
			{
				if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in group %d is getting out of a theater room seat.\n", 64, 2, leavingSeatIndex*100 + myIndex);
				if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Group %d, Customer %d getting out of seat row %d, col %d\n", 58, 4, myIndex*1000000 + leavingSeatIndex*10000 + r1*100 + c1);
				
				SetMV(GetMV(screeningRoomSeat, r1), c1, -1);
				leavingSeatIndex++;
				Yield();
			}
		}
	}
	ReleaseLock(screeningRoomLock);
	
	/*/================ Go To Bathroom ================*/
	
	/*/All follower Customers have exited their seats, ask if people want to go to the bathroom*/
	for(i8 = 0; i8 < myGroupSize; i8++)
	{
		/*/Randomly select bathroom*/
		bathroomWanted = 0;
		
		roll1 = RandInt() % 100 + 1;
		if(roll1 <= GetMV(CUSTOMER_WANT_BATHROOM_PROBABILITY,0))
		{
			bathroomWanted = 1;
		}
		
		if(bathroomWanted == 1)
		{
			if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in Group %d is going to the bathroom.\n", 51, 2, i8*100 + myIndex);
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Group %d, Customer %d wants to go to the bathroom.\n", 52, 2, myIndex*100 + i8);
			
			Yield();
			
			if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in Group %d is leaving the bathroom.\n", 50, 2, i8*100 + myIndex);
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Group %d, Customer %d left the bathroom.\n", 42, 2, myIndex*100 + i8);
		}
		else
		{
			if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Group %d, Customer %d does not want to go to the bathroom.\n", 60, 2, myIndex*100 + i8);
		}
	}
	
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: no more followers need to use the bathroom, proceeding to exit\n", 77, 1, myIndex);
	
	/*
	for(int i = 0; i < myGroupSize; i++)
	{
		followerCustomerInitLock -> Acquire();
		
		Thread* fc;
		fc = new Thread("FollowerCustomer");
		fc -> Fork(FollowerCustomer, i);
		
		followerCustomerInitCondition -> Wait();
		
		followerCustomerStartLock -> Acquire();
		followerCustomerStartLock -> Release();
	}
	
	followerCustomerStartLock -> Acquire();
	followerCustomerStartCondition -> Broadcast(followerCustomerStartLock);
	followerCustomerStartLock -> Release();
	*/
	
		
	/*/Customer exits theater and decrements count*/
	if(GetMV(PRINT_DEBUG_MESSAGES, 0)) FPrint("Customer %d: leaving theater\n", 30, 1, myIndex);
	
	AcquireLock(numCustomersInTheaterLock);
	SetMV(numCustomersInTheater, 0, GetMV(numCustomersInTheater,0) - myGroupSize);
	ReleaseLock(numCustomersInTheaterLock);
	
	AcquireLock(numGroupsInTheaterLock);
	SetMV(numGroupsInTheater, 0, GetMV(numGroupsInTheater, 0) - 1);
	ReleaseLock(numGroupsInTheaterLock);
		
	for(i9 = 0; i9 < myGroupSize; i9++)
	{
		if(GetMV(PRINT_OUTPUT_MESSAGES, 0)) FPrint("Customer %d in Group %d has exited the movie theater.\n", 55, 2, i9*100 + myIndex);
		Yield();
	}
	Exit(0);
}